﻿using BaseDll;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows.Forms;

namespace OtherDevice
{
    [Description("HY烤炉")]
    public class Oven_Six:Oven_Base
    {
        public Oven_Six(string strName) : base(strName)
        {
            controlFrom = new Form_OvenSix();
        }
        public delegate void EventRefulshOverStateDelegate(int n_Box,bool b_IsConnect, bool b_IsOpen, double d_ActTemp, double d_SetTemp,string str_Mode); 
        public static event EventRefulshOverStateDelegate EventReflushOver = null;
        /// <summary>
        /// 实际温度
        /// </summary>
        private double d_ActTemp = 0;
        /// <summary>
        /// 设定温度
        /// </summary>
        private double d_SetTemp = 0;
        /// <summary>
        /// 是否运行
        /// </summary>
        private bool b_IsOpen = false;
        /// <summary>
        /// 运行模式
        /// </summary>
        private string str_Mode = "";
        bool b_Reflush = false;
        public override void InitDeal()
        {
            m_SerialPort.DataReceived += M_SerialPort_DataReceived;
        }
        /// <summary>
        /// 数据接收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void M_SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                //烤炉返回报文格式：[地址(1B)][ID(1B)][运行状态(1B)][当前温度(4B)][当前温度设定值(4B)] [当前湿度(4B)][当前湿度设定值(4B)][开关门信号(1B)][开关门是否到位(1B)] [CRC校验码(2B)] [无意义(1B)]
                //烤炉返回报文举例：01 63 02 1B 18 00 00 7C 15 00 00 E8 1E 00 00 88 13 00 00 01 01 9B 26 CC
                //01 是仪表的地址
                //63 是ID，标识这段数据包是何种格式
                //02运行状态 0:程式停止1: 程式运行2: 定值停止3: 定值运行
                //1B 18 00 00 是当前温度值
                //7C 15 00 00 是当前温度设定值
                //E8 1E 00 00 是当前湿度
                //88 13 00 00 是当前湿度设定值
                //01         开关门信号：0 关门 ，1 开门
                //01         开关门是否到位：0 不到位，1 到位
                //9B 26     CRC16校验码， 9B为低位，26为高位
                //CC       预留位，无意义
                //串口接收到的数据
                byte[] byte_Result = null;
                ReceiveData(ref byte_Result, 6000);
                string strReceived = ArrayByteToHexStr(byte_Result);
                string[] arrayStrReceived = strReceived.Split(' ');

                int data1, data2, data3, data4, b1, b2, b3, b4, dividend, sum;
                b4 = Convert.ToInt32("1000000", 16);
                b3 = Convert.ToInt32("10000", 16);
                b2 = Convert.ToInt32("100", 16);
                b1 = Convert.ToInt32("1", 16);
                dividend = Convert.ToInt32("64", 16);
                if (byte_Result == null)
                    return;
                //解析烤炉发来的数据
                if (byte_Result.Length >= 13)
                {
                    int n_boxNo = byte_Result[0];//烤箱号
                    if (n_boxNo > 6 || n_boxNo < 1)//烤箱号不对
                    {

                    }
                    else
                    {
                        int cmdType = byte_Result[1];//命令类型
                        if (cmdType == 99)
                        {
                            int runStatus = byte_Result[2];//烤箱运行状态
                            if (runStatus == 0)//程式停止
                            {
                                b_IsOpen = false;
                                str_Mode = "程式";
                            }
                            else if (runStatus == 1)//程式运行
                            {
                                b_IsOpen = true;
                                str_Mode = "程式";
                            }
                            else if (runStatus == 2)//烤箱定值停止
                            {
                                b_IsOpen = false;
                                str_Mode = "定值";
                            }
                            else if (runStatus == 3)//烤箱定值运行
                            {
                                b_IsOpen = true;
                                str_Mode = "定值";
                            }
                            data1 = Convert.ToInt32(arrayStrReceived[3], 16);
                            data2 = Convert.ToInt32(arrayStrReceived[4], 16);
                            data3 = Convert.ToInt32(arrayStrReceived[5], 16);
                            data4 = Convert.ToInt32(arrayStrReceived[6], 16);
                            sum = data4 * b4 + data3 * b3 + data2 * b2 + data1 * b1;
                            d_ActTemp = (double)sum / (double)dividend;
                            d_ActTemp = Math.Round(d_ActTemp, 2);
                            data1 = Convert.ToInt32(arrayStrReceived[7], 16);
                            data2 = Convert.ToInt32(arrayStrReceived[8], 16);
                            data3 = Convert.ToInt32(arrayStrReceived[9], 16);
                            data4 = Convert.ToInt32(arrayStrReceived[10], 16);
                            sum = data4 * b4 + data3 * b3 + data2 * b2 + data1 * b1;
                            d_SetTemp = (double)sum / (double)dividend;
                            d_SetTemp = Math.Round(d_SetTemp, 2);
                            b_Reflush = true;
                            if (EventReflushOver != null)
                                EventReflushOver(n_boxNo,true, b_IsOpen, d_ActTemp, d_SetTemp, str_Mode);
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        public override bool Function_运行指定程序(int boxNo, int Program)
        {
            try
            {
                byte[] S = null;
                return SendAndReciveData($"E0{boxNo}#600#1#{Program}#A", ref S, 2000);
            }
            catch (Exception)
            {
                return false;
            }
        }
        public override bool Function_定值(int boxNo)
        {
            try
            {
                byte[] S = null;
                return SendAndReciveData($"E0{boxNo}#600#0#1#A", ref S, 2000);
            }
            catch (Exception)
            {
                return false;
            }
        }
        public override bool Function_程式(int boxNo)
        {
            try
            {
                byte[] S = null;
                return SendAndReciveData($"E0{boxNo}#600#0#0#A", ref S, 2000);
            }
            catch (Exception)
            {
                return false;
            }

        }
        public override bool Function_设置温度(int boxNo, double d_SetTem)
        {
            byte[] S = null;
            return SendAndReciveData($"E0{boxNo}#62#01#02#{d_SetTem}#A", ref S, 2000);

        }
        public override bool Function_开始加热(int boxNo)
        {
            try
            {
                byte[] S = null;
                return SendAndReciveData($"E0{boxNo}#99#1#A", ref S, 2000);
            }
            catch (Exception)
            {
                return false;
            }

        }
        public override bool Function_停止加热(int boxNo)
        {
            try
            {
                byte[] S = null;
                return SendAndReciveData($"E0{boxNo}#99#2#A", ref S, 2000);
            }
            catch (Exception)
            {
                return false;
            }

        }
        object objSendSensorLock = new object();
        public override bool Function_获取炉子状态(int boxNo,ref bool b_IsConnect,ref double d_ActTemp, ref double d_SetTemp, ref bool b_IsOpen,ref string str_Mode)
        {
            lock (objSendSensorLock)
            {
                try
                {
                    SendData($"S0{boxNo}#99#A");
                    b_Reflush = false;
                    Stopwatch stopWatch = new Stopwatch();
                    stopWatch.Restart();
                    while (true)
                    {
                        if (stopWatch.ElapsedMilliseconds > 3000)
                        {
                            if (EventReflushOver != null)
                                EventReflushOver(boxNo, false, false, 0, 0, "None");
                            return false;
                        }
                        if (b_Reflush)
                            break;
                        Thread.Sleep(50);
                    }
                    b_IsConnect = true;
                    d_ActTemp = this.d_ActTemp;
                    d_SetTemp = this.d_SetTemp;
                    b_IsOpen = this.b_IsOpen;
                    str_Mode = this.str_Mode;
                    return true;
                }
                catch (Exception ex)
                {
                    b_IsConnect = true;
                    if (EventReflushOver != null)
                        EventReflushOver(boxNo, false, false, 0, 0, "None");
                    MessageBox.Show("发送获取温度指令失败" + ex.Message);
                    return false;
                }
            }

        }
    }

    
}